package com.zhentao.utils;

import io.jsonwebtoken.*;
import org.springframework.scheduling.annotation.Scheduled;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

public class AppJwtUtil {

    // TOKEN的有效期一天（S）
    private static final int TOKEN_TIME_OUT = 3_600;
    // 加密KEY
    private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
    // 最小刷新间隔(S)
    private static final int REFRESH_TIME = 300;

    // 生产ID
    public static String getToken(Long id){
        Map<String, Object> claimMaps = new HashMap<>();
        claimMaps.put("id",id);
        long currentTime = System.currentTimeMillis();
        return Jwts.builder()
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date(currentTime))  //签发时间
                .setSubject("system")  //说明
                .setIssuer("") //签发者信息
                .setAudience("app")  //接收用户
                .compressWith(CompressionCodecs.GZIP)  //数据压缩方式
                .signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
                .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000))  //过期时间戳
                .addClaims(claimMaps) //cla信息
                .compact();
    }

    /**
     * 获取token中的claims信息
     *
     * @param token
     * @return
     */
    private static Jws<Claims> getJws(String token) {
            return Jwts.parser()
                    .setSigningKey(generalKey())
                    .parseClaimsJws(token);
    }

    /**
     * 获取payload body信息
     *
     * @param token
     * @return
     */
    public static Claims getClaimsBody(String token) {
        try {
            return getJws(token).getBody();
        }catch (ExpiredJwtException e){
            return null;
        }
    }

    /**
     * 获取hearder body信息
     *
     * @param token
     * @return
     */
    public static JwsHeader getHeaderBody(String token) {
        return getJws(token).getHeader();
    }

    /**
     * 是否过期
     *
     * @param claims
     * @return -1：有效，0：有效，1：过期，2：过期
     */
    public static int verifyToken(Claims claims) {
        if(claims==null){
            return 1;
        }
        try {
            claims.getExpiration()
                    .before(new Date());
            // 需要自动刷新TOKEN
            if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){
                return -1;
            }else {
                return 0;
            }
        } catch (ExpiredJwtException ex) {
            return 1;
        }catch (Exception e){
            return 2;
        }
    }

    /**
     * 由字符串生成加密key
     *
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    public static void main(String[] args) {
       /* Map map = new HashMap();
        map.put("id","11");*/
        System.out.println(AppJwtUtil.getToken(1102L));
        Jws<Claims> jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA");
        Claims claims = jws.getBody();
        System.out.println(claims.get("id"));

    }






//    public void addTaskToRedis(Products products){
//        try {
//            String currentTime = "submit:currenttime"+products.getTaskid();
//            String futureTime = "submit:futuretime"+products.getTaskid();
//            System.err.println(products.getScheduledPublishTime().getTime());
//            System.err.println(System.currentTimeMillis());
//            //如果执行时间>当前时间 并且 执行时间《=当前时间+5分钟  ---》zSet
//            if (products.getScheduledPublishTime().getTime() <= System.currentTimeMillis()){
//                System.out.println("执行时间小于等于当前时间---》list"+products);
//                try {
//                    redisTemplate.opsForList().leftPush(currentTime, products);
//                } catch (Exception e) {
//                    System.err.println("添加任务到Redis时发生异常: " + e.getMessage());
//                    e.printStackTrace();
//                }
//            }
//
//
//            //如果执行时间>=当前时间+5分钟  --先不管 【5分钟扫描一次数据库--？zset】
//            if(products.getScheduledPublishTime().getTime() > System.currentTimeMillis() &&products.getScheduledPublishTime().getTime()<= System.currentTimeMillis()+5*60*1000){
//
//                System.out.println("未来5分钟的数据-----》zset"+products);
//                redisTemplate.opsForZSet().add(futureTime,products,products.getScheduledPublishTime().getTime());
//            }
//        } catch (Exception e) {
//            System.err.println("添加任务到Redis时发生异常: " + e.getMessage());
//            e.printStackTrace();
//        }
//    }
//
//    @Scheduled(cron = "0 */1 * * * ?")
//    public void zSetToList() throws InterruptedException {
//        System.out.println("每分钟执行一次--》数据从zSet--->list里面");
//
//        String currentTime = "submit:currenttime"+1;
//        String futureTime = "submit:futuretime"+1;
//
//        Set<Object> sets =
//                redisTemplate.opsForZSet().range(futureTime, 0, -1); // 0 表示从第一个元素开始，-1 表示最后一个元素
//        System.err.println(sets);
//        //1.获取要消费的数据
//        Set<Object> set =
//                redisTemplate.opsForZSet().rangeByScore(futureTime, 0, System.currentTimeMillis());
//
//
//        //2 把这些数据--》list
//        for(Object object:set){
//            System.out.println("把zset的数据放到list里面");
//            redisTemplate.opsForList().leftPush(currentTime, object);
//            Thread.sleep(8000);
//            //把取出来的数据从zSet里面给删除掉
//            redisTemplate.opsForZSet().remove(futureTime,object);
//        }
//    }
}
